home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Aminet 28
/
Aminet 28 (1998)(GTI - Schatztruhe)[!][Dec 1998].iso
/
Aminet
/
game
/
board
/
Crafty-15.19.lha
/
crafty-15.19
/
src
/
searchr.c
< prev
next >
Wrap
C/C++ Source or Header
|
1998-09-13
|
12KB
|
299 lines
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "chess.h"
#include "data.h"
#include "epdglue.h"
/* modified 06/05/98 */
/*
********************************************************************************
* *
* SearchRoot() is the recursive routine used to implement the alpha/beta *
* negamax search (similar to minimax but simpler to code.) SearchRoot() is *
* only called when ply=1. it is somewhat different from Search() in that *
* some things (null move search, hash lookup, etc.) are not useful at the *
* root of the tree. SearchRoot() calls Search() to search any positions *
* that are below ply=1. *
* *
********************************************************************************
*/
int SearchRoot(TREE *tree, int alpha, int beta, int wtm, int depth) {
register int first_move=1;
register int initial_alpha, value;
register int extensions, begin_root_nodes;
/*
----------------------------------------------------------
| |
| initialize. set NextMove() status to 0 so it will |
| know what has to be done. |
| |
----------------------------------------------------------
*/
tree->in_check[2]=0;
tree->extended_reason[2]=no_extension;
initial_alpha=alpha;
RepetitionCheck(tree,1,wtm);
tree->in_check[1]=Check(wtm);
tree->next_status[1].phase=ROOT_MOVES;
/*
----------------------------------------------------------
| |
| now iterate through the move list and search the |
| resulting positions. note that Search() culls any |
| move that is not legal by using Check(). the special |
| case is that we must find one legal move to search to |
| confirm that it's not a mate or draw. |
| |
----------------------------------------------------------
*/
while ((tree->current_phase[1]=NextRootMove(tree,wtm))) {
tree->extended_reason[1]=0;
#if !defined(FAST)
if (1 <= trace_level)
SearchTrace(tree,1,depth,wtm,alpha,beta,"SearchRoot",tree->current_phase[1]);
#endif
/*
----------------------------------------------------------
| |
| if we push a pawn to the 7th rank, we need to look |
| deeper to see if it can promote. |
| |
----------------------------------------------------------
*/
extensions=-60;
if (Piece(tree->current_move[1])==pawn &&
((wtm && To(tree->current_move[1]) > H5 && TotalBlackPieces<16 &&
!And(mask_pawn_passed_w[To(tree->current_move[1])],BlackPawns)) ||
(!wtm && To(tree->current_move[1]) < A4 && TotalWhitePieces<16 &&
!And(mask_pawn_passed_b[To(tree->current_move[1])],WhitePawns)) ||
push_extensions[To(tree->current_move[1])]) &&
Swap(tree,From(tree->current_move[1]),To(tree->current_move[1]),wtm) >= 0) {
tree->extended_reason[1]|=passed_pawn_extension;
tree->passed_pawn_extensions_done++;
extensions+=pushpp_depth;
}
/*
----------------------------------------------------------
| |
| now make the move and search the resulting position. |
| |
----------------------------------------------------------
*/
MakeMove(tree,1,tree->current_move[1],wtm);
/*
----------------------------------------------------------
| |
| if the move to be made checks the opponent, then we |
| need to remember that he's in check and also extend |
| the depth by one ply for him to get out. |
| |
----------------------------------------------------------
*/
if (Check(ChangeSide(wtm))) {
tree->in_check[2]=1;
tree->extended_reason[2]=check_extension;
tree->check_extensions_done++;
extensions+=incheck_depth;
}
else {
tree->in_check[2]=0;
tree->extended_reason[2]=no_extension;
}
/*
----------------------------------------------------------
| |
| now call Search to produce a value for this move. |
| |
----------------------------------------------------------
*/
begin_root_nodes=tree->nodes_searched;
extensions=Min(extensions,0);
if (first_move) {
value=-ABSearch(tree,-beta,-alpha,ChangeSide(wtm),
depth+extensions,2,DO_NULL);
if (abort_search) {
UnMakeMove(tree,1,tree->current_move[1],wtm);
return(alpha);
}
first_move=0;
}
else {
value=-ABSearch(tree,-alpha-1,-alpha,ChangeSide(wtm),
depth+extensions,2,DO_NULL);
if (abort_search) {
UnMakeMove(tree,1,tree->current_move[1],wtm);
return(alpha);
}
if ((value > alpha) && (value < beta)) {
value=-ABSearch(tree,-beta,-alpha,ChangeSide(wtm),
depth+extensions,2,DO_NULL);
if (abort_search) {
UnMakeMove(tree,1,tree->current_move[1],wtm);
return(alpha);
}
}
}
tree->root_nodes[root_move]=tree->nodes_searched-begin_root_nodes;
if (value > alpha) {
SearchOutput(tree,value,beta);
if(value >= beta) {
History(tree,1,depth,wtm,tree->current_move[1]);
UnMakeMove(tree,1,tree->current_move[1],wtm);
StoreRefutation(tree,1,depth,wtm,value,0);
return(value);
}
alpha=value;
root_value=alpha;
beta=alpha+30;
root_beta=beta;
}
UnMakeMove(tree,1,tree->current_move[1],wtm);
}
/*
----------------------------------------------------------
| |
| all moves have been searched. if none were legal, |
| return either MATE or DRAW depending on whether the |
| side to move is in check or not. |
| |
----------------------------------------------------------
*/
if (abort_search) return(0);
if (first_move == 1) {
value=(Check(wtm)) ? -(MATE-1) : DrawScore(root_wtm==wtm);
if (value >=alpha && value <beta) {
SavePVS(tree,1,value,0);
#if !defined(FAST)
if (1 <= trace_level) printf("Search() no moves! ply=1\n");
#endif
}
return(value);
}
else {
if (alpha != initial_alpha) {
memcpy(&tree->pv[0].path[1],&tree->pv[1].path[1],(tree->pv[1].path_length)*4);
memcpy(&tree->pv[0].path_hashed,&tree->pv[1].path_hashed,3);
History(tree,1,depth,wtm,tree->pv[1].path[1]);
}
StoreBest(tree,1,depth,wtm,alpha,initial_alpha,0);
return(alpha);
}
}
/* modified 03/11/98 */
/*
********************************************************************************
* *
* SearchOutput() is used to print the principal variation whenever it *
* changes. one additional feature is that SearchOutput() will try to do *
* something about variations truncated by the transposition table. if the *
* variation was cut short by a transposition table hit, then we can make the *
* last move, add it to the end of the variation and extend the depth of the *
* variation to cover it. *
* *
********************************************************************************
*/
void SearchOutput(TREE *tree, int value, in